/**	
*	
	Doyle Spiral
*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Polygon;


import pluginUtils.DoyleCircle;


public class doyle0_ extends ImagePlus implements PlugIn {
	private ImageProcessor primeIP; 
	private int X=2000,Y=2000;
	private boolean first=true; 
	private void drawCircle(DoyleCircle c){
		int intX=(int)(c.getXcenter()*X);
		int intY=(int)(c.getYcenter()*Y);
		int intR=(int)(c.getRadius()*X); // X ??
		primeIP.drawOval(intX-intR,intY-intR,intR*2,intR*2);
		if(first){
		primeIP.fillOval(intX-5,intY-5,10,10);
		first=false; 
		}
		
	}
	

	public void run(String arg) {
		primeIP = new ColorProcessor(X,Y);
		double a=2; 
		double  n=3; 
		double  m=2; 
		//double blog=(n+0.0)/m*Math.log(a); 
		//double b=Math.exp(blog); 
		double b=Math.pow(a,(n+0.0)/m);
		System.out.println(a+" "+b);
		DoyleCircle.setBounds(0,0);
		
		// Calcul des angles
		double u[]={1+1/a+b/a,1+1/a+1/b,1+1/b+a/b,1+a+a/b,1+a+b,1+b+b/a};//1+a+a*b en 5eme pos
		double theta[]={Math.acos((u[0]-b/(a*a))/(u[0]+b/(a*a))),
						Math.acos((u[1]-1/(a*b))/(u[1]+1/(a*b))),
						Math.acos((u[2]-a/(b*b))/(u[2]+a/(b*b))),
						Math.acos((u[3]-a*a/b)/(u[3]+a*a/b)),
						Math.acos((u[4]-a*b)/(u[4]+a*b)),
						Math.acos((u[5]-b*b/a)/(u[5]+b*b/a))
		};
		
		// debug-test : calcul d'un angle de rotation
		// Rotation pour le premier sous-cercle
		double uprov=u[5]*b/a; 
		double alpha=Math.acos((uprov-b)/(uprov+b)); 
		System.out.println("alpha "+alpha*180/Math.PI); 
		double rotat=alpha-Math.PI+theta[4]+theta[5]; 
		System.out.println("rotation "+rotat*180/Math.PI);
		
		// deuxieme cercle (en test)
		double uprov2=u[0]*b/a; 
		double gamma=Math.acos((uprov2-1/a)/(uprov2+1/a));
		double rotat2=theta[5]-gamma; 
		System.out.println("gamma :"+gamma*180/Math.PI+" rotat2 "+rotat2*180/Math.PI); 
		/*double sum=0; 
		for(int i=0;i<5;i++)sum+=theta[i];
		theta[5]=2*Math.PI-sum; */
		double radiusCoef[]={b/a,1.0/a,1.0/b,a/b,a,b};
		
		
		double rotationAngle[]=new double[6]; 
		rotationAngle[0]=rotat; 
		rotationAngle[1]=rotat2;
		rotationAngle[2]=-Math.PI+(theta[0]+theta[1]+theta[5]);
		rotationAngle[3]=-Math.PI+(theta[0]+theta[1]+theta[2]); 
		//rotationAngle[4]=-Math.PI+(theta[0]+theta[1]+theta[2]);
		
		// cinquieme cercle
		double uprov5=u[4]*a;
		double delta=Math.acos((uprov5-b)/(uprov5+b));
		double beta=Math.PI-(theta[4]+theta[5]); 
		rotationAngle[4]=beta-delta; 
		
		// sixieme cercle
		double uprov6=u[5]*b;
		double eta=Math.acos((uprov6-b/a)/(uprov6+b/a));
		rotationAngle[5]=Math.PI-theta[5]-eta-theta[0];  
		
		
		
		double somme=0; 
		for(int i=0;i<6;i++){
			somme+=theta[i]; 
			System.out.println(theta[i]*180/Math.PI+" "+somme*180/Math.PI); 
		}
		/*******************************************************/
		DoyleCircle init=new DoyleCircle(0.5,0.5,Math.PI,0.05,0,0); 
		
		Polygon background=new Polygon(new int[]{0,0,X,Y},new int[]{0,X,Y,0},4);
		primeIP.setColor(new Color(0.9f,0.9f,0.82f));
		
		primeIP.fillPolygon(background);
		primeIP.setColor(new Color(0.9f,0.0f,0.82f));
		drawCircle(init);
		
		double theta0=init.getRotation(); 
		DoyleCircle current[]=new DoyleCircle[6]; 
		for(int i=0;i<6;i++){
			double rad=init.getRadius()*(1+radiusCoef[i]); 
			double nX=init.getXcenter()+rad*Math.cos(theta0);
			double nY=init.getYcenter()+rad*Math.sin(theta0);
			
			current[i]=new DoyleCircle(nX,nY,init.getRotation()+rotationAngle[i],init.getRadius()*radiusCoef[i],0,0); //tourne+theta[i]);
			drawCircle(current[i]);
			//primeIP.fillOval((int)(X*nX), (int)(Y*nY),10,10); 
			theta0+=theta[i];
		}
		
		
		
		primeIP.setColor(new Color(0.0f,0.0f,0.82f));
		for(int ci=0; ci<6;ci++){ // each circle
			if(ci!=-1){
			//theta0=rotationAngle[ci]; 
			theta0=current[ci].getRotation(); 
			for(int i=0;i<6;i++){ // six circles tangent to circle[ci]
				double rad=current[ci].getRadius()*(1+radiusCoef[i]); 
				double nX=current[ci].getXcenter()+rad*Math.cos(theta0);
				double nY=current[ci].getYcenter()+rad*Math.sin(theta0);
				DoyleCircle cur=new DoyleCircle(nX,nY,0,current[ci].getRadius()*radiusCoef[i],0,0); //tourne+theta[i]);
				drawCircle(cur);
				theta0+=theta[i];
			}
			}
			
		}
		
		
		
		
		setProcessor("Verifying", primeIP);
		show();
	}

	

}
